Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add rbeesley's ansi-color.cmd, a CMD-based color tool (& more) #11932

Merged
37 commits merged into from
Jan 4, 2022

Conversation

rbeesley
Copy link
Contributor

@rbeesley rbeesley commented Dec 13, 2021

Adds the Ansi-Color tool, completing #6470.

What started out as an experiment to see the support of ANSI support to
conhost, I wanted to write a Windows equivalent of Daniel Crisman's
BASH script on tldp.org. I didn't like how the BASH script hard coded
in whitespace and I thought Windows could do better. I applied
techniques to speed up the execution and tried to use the Command Script
batch language in ways that pushed the limits for what I thought it
could do. Running this from withing PowerShell, &cmd /c ansi-color.cmd,
I found out that the active code page is already 65001, but when ran
from a Command Prompt, the active code page depends on the regional
settings and I would have a dependency on CHCP to detect the active code
page, change to 65001 if necessary, and restore the previous code page
after running. I found it useful for designing color schemes and writing
shaders, and I started using an earlier version for logging bugs.

Initially it was a single script which I would dump every SGR
combination I could think of, and many which weren't implemented yet,
but as I was looking at other tools which had been written I wanted to
mimic the same output so I could do side-by-side comparisons. First I
wrote crisman.def and then colortool.def. So I had to align text.
Then output was slow for big tables so I wrote to an outbuffer and made
use of macros. I wanted to handle flags instead of needing to change
settings every time, so I added argument parsing and loading external
files.

It's a batch file that has some really useful purposes and does nothing
I've seen before.

I've ran every definition in a Command Prompt, with CP 437 and CP 65001
to make sure it works. Posted as a Gist on my account for about year, a
Portuguese (Brazilian as I recall), speaking user tried the Gist and it
was failing because CHCP is localized. I've taken an approach to try and
make it work for different localizations, but this is a potential
problem. I also ran every definition in PowerShell 7, shelling down to
cmd to actually run it. Lastly, I went through using the flags and
made sure that help would be shown. Error messages generate error levels
when the script exits, so those could be used to use this in an
automated test and catch if there was a problem with the script
executing. It won't be able to validate if the generated output shows
correctly, but it would fail if a definition file is missing or if it
needed to switch to Unicode and wasn't flagged or configured to do so.
For trying to build the table stub and headers, there is some debug code
which will output what was parsed. This is the last debug code in the
script itself, but I found it to be useful at times, so there is a
configuration setting which can turn that debug output back on.
Technically there is also a debug statement to break after adding the
macros and parsing the arguments, but before it does any configuration
changes, changes the code page, or anything. This was useful for making
changes to macros and being able to test them as well as making sure
that flags and arguments are parsed correctly. It was a rather cryptic
discovery to call cmd /c exit -1073741510 to break out, so in part
that was my reason to leave this in. The definition files themselves
could be cleaned up further, but in both of them there are a lot of
Unicode codepoints that could be useful when defining division lines for
the headers so I opted to just comment them out. I initially had the
default definition to require Unicode, but now it just changes to a
non-Unicode output if it can't. And this brings up the last concern. The
way certain settings are set, is that they are defined in the
__TABLE__ section of the definition file. With PARSE_TABLE_DATA,
the script looks line by line for SET * or IF * and if found it will
effectively eval that line. The definition files are written so that for
instance SET "CELL= gYw " could be used to set the code which is used.
If was allow so that there could be a test if Unicode were available
and set something different for ASCII and Unicode. But it also opens the
possibility that a rogue actor could create a ansi-color.cmd
definition file something like SET "foo=bar" & DoSomethingBad.exe.
First of all I'd be flattered that anyone would use this very niche
tool, but it is something I think which needs to be called out.
Essentially the definition files are just batch files, but they are
extremely limited to executing only one line at a time and only
supporting IF and SET commands. I think this is a minimal risk because
at that point batch files would already be more effective, but there
should also be an expectation that a batch file will run something and
the same may not be true for the heavily degraded definition files. I
think the risk is minimal but it is a risk I wanted to make clear. This
really showcases some interesting techniques and ideas, and I hope that
it is useful. All told, there are a couple years of incremental changes
in this PR.

Closes #6470

@ghost ghost added Area-CodeHealth Issues related to code cleanliness, linting, rules, warnings, errors, static analysis, etc. Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Product-Meta The product is the management of the products. labels Dec 13, 2021
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@zadjii-msft
Copy link
Member

tried to use the Command Script batch language in ways that pushed the limits for what I thought it could do

holy shit yeah it does. I've never seen a batch script anything like this before, but it's kinda incredible like that. You should probably throw your username at the top of this script in a cooment as the author, because you deserve the credit for whatever witchcraft this is.

I'm cool accepting this as a tool to our repo, because it would be handy for debugging purposes, likely moreso than colortool itself. Lemme double-check that the rest of the team shares that consensus ☺️

@zadjii-msft zadjii-msft added the Needs-Discussion Something that requires a team discussion before we can proceed label Dec 13, 2021
@zadjii-msft
Copy link
Member

team consensus:

  • this is a testament to what is possible with batch scripting
  • no way in heck do any of us fully understand how it works, so maintaining this would be likely impossible
  • Would this be simpler as a C/C++ program? yea probably
  • Will we accept it as is? Yea probably. It's a monument to batch scripting so it's pretty cool on that merit alone. Plus, it's a tool. It's not part of the CI, it's not something that ships, it's just a nice debug utility.

:shipit:

@zadjii-msft zadjii-msft removed the Needs-Discussion Something that requires a team discussion before we can proceed label Dec 13, 2021
Added a way to get the errorlevel from the CHCP call. If it fails, we
can still use the result if there isn't a need for UTF-8. This should
be more robust and should allow things to work even if CHCP isn't on a
system for some reason. The consideration is that there might be a
localization where this doesn't work so try to fail gracefuly. I also
cleaned up the way help and internal errors are handled better now.
Requesting help doesn't set an error level for internal commands, so
this app won't either. Finally, addressed the speling errers I had in
the first checkin. Forground (sic) is intentional because that is the
spelling in the original BASH script. Other errors raised I corrected.
I've tried to leave comments throughout, but if there is anything not
understood, I can try to document it more.
@github-actions
Copy link

github-actions bot commented Dec 14, 2021

@check-spelling-bot Report

Unrecognized words, please review:

  • CMDs
Previously acknowledged words that are now absent Relayout
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the [email protected]:rbeesley/terminal.git repository
on the 6470-Command-Shell-Script-ColorTool branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect/205c1ec487b80f127ca611d10b973f66d9ed6812.txt
.github/actions/spelling/expect/alphabet.txt
.github/actions/spelling/expect/expect.txt
.github/actions/spelling/expect/web.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect/246e57f1b2f1de95f365799870f8f0cd9d87299f.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/microsoft/terminal/issues/comments/993336748" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

⚠️ The command is written for posix shells. You can copy the contents of each perl command excluding the outer ' marks and dropping any '"/"' quotation mark pairs into a file and then run perl file.pl from the root of the repository to run the code. Alternatively, you can manually insert the items...

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

🗜️ If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to a patterns/{file}.txt.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

@rbeesley
Copy link
Contributor Author

It may read like Perl at times, but it should be complete now. If there is something you think is unclear, I can try to add more documentation, but I think the comments in the script should answer most questions and I tried to make the flow very modular. The main thing to remember is that to define the macros they need to be defined early on, but I wanted to add the configuration and data segment at the top. Configuration allows someone to set the condition of a flag, so they don't have to be passed on the command-line... actually that was the way this script was originally written, and the argument parsing was added later. Defining the CELL here is just a way to define something which doesn't have to be in definition files, and it actually makes it possible to use different definition files where just changing this one place changes whatever else is ran. I'm not sure any of the definitions I included use this technique, but you can imagine other ways this could be extended. The built-in definition is what I usually ran to review changes from build to build and when authoring color schemes. The main script doesn't start until about 362 lines in, but even this is designed to be very readable. Until 490, it is just trying to set the correct default values and settings, including changing the codepage if necessary. Then it reads the data segment, validates that the configuration supports the requirements of the definition, specifically UTF-8, then it resolves how the divisions should be drawn between table headings, cells, stubs, etc. Lastly it builds the table to a buffer and writes the buffer to the screen. After that it restores the codepage if it changed and exists. With labels and comments, I think it shouldn't be too difficult to read, but I've also rewritten it several times as I've introduced new functionality. As mentioned, it is a tool and a great demonstration that Command Scripting can accomplish more than expected.

If there is an IF which checks for a string in a definition file, it is
now case insensitive and shouldn't cause problems. Updated error output
when CHCP fails and only show a warning if Unicode isn't required. If
Unicode is required, then show an additional error and exit. This has a
negative that even if the shell is running on codepage 65001, it will
block the execution of a definition file which requests UTF8 or the flag
is set. The error in this case still makes sense as this happens when
trying to read the active codepage and the utility will not know if this
fails at this point in execution. I think this is the right balance.
If there is anything evaluated which can cause an error this should be
caught now. Trimmed the data before it is further evaluated to make sure
extra whitespace is dropped but you can't indent in the definition
files. Trimming before checking segments would fix this, but introduces
a performance hit.
@rbeesley
Copy link
Contributor Author

I'm happy with the current state. I made a few more changes to improve CHCP error handling and how things downgrade if that fails. Since the initial PR, I've also cleaned up the reading of the Data Segment so that it is more forgiving of case inconsistencies. There is more which could be done, but it seems to introduce performance problems to handle things like indentation in the definition files. It would be a nice to have, but probably not at that cost.

Adding #SPC# to a column definition will do the same as adding a #SPC#
to a row, in that it will add visual separation. This is unlike #NUL#
which just doesn't apply an associated escape sequence but still
writes the test text to a cell. #SPC# writes spaces instead. Also
updated a couple of definitions which benefit from this change. Fixed
sgr-intensity.def so that is shows intensity from low to high, flipping
1; and 2; attributes.
Fixed a case where special tokens were interpreted as column width for
the stub so now they are 0 width. This allows the labels to be inserted
into the middle of the table without affecting the overall width.
Added a new definition for showing attributes and a label definition
to demonstrate how labels can be used. They follow the pattern used for
ECHO so that #LBL#[.| ][TEXT] will output the same way ECHO does.
#LBL# can also use CSI commands to format the label. #LBL# will
automatically apply RESET at the end of a line to prevent inconsistency.
@github-actions
Copy link

github-actions bot commented Dec 29, 2021

@check-spelling-bot Report

Unrecognized words, please review:

  • mdecreased
  • mincreased
Previously acknowledged words that are now absent adaa coffgroup coffgrp datetime eae emplate GENPROFILE HHmm Hostx installationpath MMdd pgorepro pgort PGU Relayout
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the [email protected]:rbeesley/terminal.git repository
on the 6470-Command-Shell-Script-ColorTool branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect/205c1ec487b80f127ca611d10b973f66d9ed6812.txt
.github/actions/spelling/expect/alphabet.txt
.github/actions/spelling/expect/expect.txt
.github/actions/spelling/expect/web.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect/1e22bfa8d6f86d0546c3f162d171274cf453db65.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/microsoft/terminal/issues/comments/1002330618" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

⚠️ The command is written for posix shells. You can copy the contents of each perl command excluding the outer ' marks and dropping any '"/"' quotation mark pairs into a file and then run perl file.pl from the root of the repository to run the code. Alternatively, you can manually insert the items...

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

🗜️ If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to a patterns/{file}.txt.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

Added: mdecreased mincreased
Removed: adaa coffgroup coffgrp datetime eae emplate GENPROFILE
HHmm Hostx installationpath MMdd pgorepro pgort PGU Relayout
Moved additional words from previous checkins to appropriate files
@jsoref
Copy link
Contributor

jsoref commented Dec 31, 2021

Re:

!CSI!2m

I recently added an ANSI color codes pattern to https://github.com/check-spelling/check-spelling/wiki/Configuration-Examples:-patterns:

# ANSI color codes
\\u001b\[\d+(?:;\d+|)m

You could probably do:

# ANSI color codes
!CSI!d+(?:;\d+|)m

@rbeesley
Copy link
Contributor Author

@jsoref, thanks for the feedback. I looked at the CSI pattern you suggested. I think it would actually need to be something like: (?i)!CSI!(?-i)(?:\d*[ABCDEFGJKST]|\d*;?\d*[HRf]|(?:\d+(?:;\d+|)+)?m|[45]i|6n), and I'm not sure that is going to suffice. It covers the following types of patterns as I've defined them in the script:

!CSI!m   # RESET
!csi!1m   # Intensity attribute with lower-case CSI variable... (this is cmd scripting so this is allowed)
!CSI!2;21;30m   # Faint, Double-Underscore, Black Foreground
!CSI!F   # Cursor Previous Line

And it supports all the CSI sequences I could quickly scrounge up. The problem I have with making this a pattern is that this isn't exhaustive. I know that it is an incomplete set of what could be available, and I don't know the set that Windows Terminal supports.

Something like (?i)!CSI!(?-i)(?:(?:\d+(?:;\d+|)+)?[A-Za-z]) is a little more general, or even (?i)!CSI!(?-i)(?:(?:;?\d|)+?[A-Za-z]) might be better, but very broad. Lastly, something like ![Cc][Ss][Ii]!(?:(?:;?\d|)+?[A-Za-z]) if the pattern checker wouldn't handle the case insensitivity flags, but I believe it is PCRE, so it should work.

The base minimum, following your example would be !CSI!\d+(?:;\d+|)m, you were missing a slash for the first digit.

Too much? Not enough? Using a pattern would probably be better but I'm not sure how deep to take this.

@jsoref
Copy link
Contributor

jsoref commented Dec 31, 2021

Sorry about the lost slash.

Personally I think that something is better than nothing, and it's an invitation for someone to improve it later. As long as you don't lose anything because of false positives, I see a pattern as a strict improvement.

Fwiw, Instead of using the fancy (?-i), I'd just do this:

!(?:(?i)CSI)...

@rbeesley
Copy link
Contributor Author

@jsoref, nice. I didn't consider that the insensitivity could be applied in the non-capturing group, but of course it could.

!(?:(?i)CSI)!\d+(?:;\d+|)m

That's more readable than the form where you break it up into one character of groups. Final answer.

@jsoref
Copy link
Contributor

jsoref commented Dec 31, 2021

I should have clarified: the pattern matcher is Perl.

The comment includes customizable content:
https://github.com/microsoft/terminal/blob/main/.github/actions/spelling/advice.md

Here's my current default (which was written long after the above):
https://github.com/check-spelling/spell-check-this/blob/prerelease/.github/actions/spelling/advice.md

It looks like the patterns description in the advice could be clarified. If you're up for it, please feel free, otherwise maybe with my next upgrade PR, I'll see about adjusting it.

(I'm very close to a new release, but still beating some bugs out....

Added a separator.def which can model using separator variables in a
definition file. For the table code to be "complete" there would need to
be a border and row separators, but it seems like that would have low
value as it would just grow the height without additional benefit.
Similarly, borders would grow the width and height by two with no real
perceived gain.
@github-actions
Copy link

github-actions bot commented Jan 3, 2022

@check-spelling-bot Report

Unrecognized words, please review:

  • interesect
Previously acknowledged words that are now absent pgorepro pgort PGU
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the [email protected]:rbeesley/terminal.git repository
on the 6470-Command-Shell-Script-ColorTool branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect/alphabet.txt
.github/actions/spelling/expect/expect.txt
.github/actions/spelling/expect/web.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect/b61b24ecd1f59a9332f45edd055767b155f91bb0.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/microsoft/terminal/issues/comments/1004289223" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

⚠️ The command is written for posix shells. You can copy the contents of each perl command excluding the outer ' marks and dropping any '"/"' quotation mark pairs into a file and then run perl file.pl from the root of the repository to run the code. Alternatively, you can manually insert the items...

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

🗜️ If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to a patterns/{file}.txt.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

and renamed SEPARATOR.COL_INTERSECT to SEPARATOR.CELL_INTERSECT to
better describe its use. Added a fgbg.def which gives a dense compact
view of all FG and BG colors.
@github-actions
Copy link

github-actions bot commented Jan 3, 2022

@check-spelling-bot Report

Unrecognized words, please review:

  • fgbg
  • rvpa
Previously acknowledged words that are now absent pgorepro pgort PGU
To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands

... in a clone of the [email protected]:rbeesley/terminal.git repository
on the 6470-Command-Shell-Script-ColorTool branch:

update_files() {
perl -e '
my @expect_files=qw('".github/actions/spelling/expect/alphabet.txt
.github/actions/spelling/expect/expect.txt
.github/actions/spelling/expect/web.txt"');
@ARGV=@expect_files;
my @stale=qw('"$patch_remove"');
my $re=join "|", @stale;
my $suffix=".".time();
my $previous="";
sub maybe_unlink { unlink($_[0]) if $_[0]; }
while (<>) {
if ($ARGV ne $old_argv) { maybe_unlink($previous); $previous="$ARGV$suffix"; rename($ARGV, $previous); open(ARGV_OUT, ">$ARGV"); select(ARGV_OUT); $old_argv = $ARGV; }
next if /^(?:$re)(?:(?:\r|\n)*$| .*)/; print;
}; maybe_unlink($previous);'
perl -e '
my $new_expect_file=".github/actions/spelling/expect/ff7f569096bb3bc8d22ab8e3f69041be3d595042.txt";
use File::Path qw(make_path);
use File::Basename qw(dirname);
make_path (dirname($new_expect_file));
open FILE, q{<}, $new_expect_file; chomp(my @words = <FILE>); close FILE;
my @add=qw('"$patch_add"');
my %items; @items{@words} = @words x (1); @items{@add} = @add x (1);
@words = sort {lc($a)."-".$a cmp lc($b)."-".$b} keys %items;
open FILE, q{>}, $new_expect_file; for my $word (@words) { print FILE "$word\n" if $word =~ /\w/; };
close FILE;
system("git", "add", $new_expect_file);
'
}

comment_json=$(mktemp)
curl -L -s -S \
  --header "Content-Type: application/json" \
  "https://api.github.com/repos/microsoft/terminal/issues/comments/1004404683" > "$comment_json"
comment_body=$(mktemp)
jq -r .body < "$comment_json" > $comment_body
rm $comment_json

patch_remove=$(perl -ne 'next unless s{^</summary>(.*)</details>$}{$1}; print' < "$comment_body")
  

patch_add=$(perl -e '$/=undef;
$_=<>;
s{<details>.*}{}s;
s{^#.*}{};
s{\n##.*}{};
s{(?:^|\n)\s*\*}{}g;
s{\s+}{ }g;
print' < "$comment_body")
  
update_files
rm $comment_body
git add -u
✏️ Contributor please read this

By default the command suggestion will generate a file named based on your commit. That's generally ok as long as you add the file to your commit. Someone can reorganize it later.

⚠️ The command is written for posix shells. You can copy the contents of each perl command excluding the outer ' marks and dropping any '"/"' quotation mark pairs into a file and then run perl file.pl from the root of the repository to run the code. Alternatively, you can manually insert the items...

If the listed items are:

  • ... misspelled, then please correct them instead of using the command.
  • ... names, please add them to .github/actions/spelling/allow/names.txt.
  • ... APIs, you can add them to a file in .github/actions/spelling/allow/.
  • ... just things you're using, please add them to an appropriate file in .github/actions/spelling/expect/.
  • ... tokens you only need in one place and shouldn't generally be used, you can add an item in an appropriate file in .github/actions/spelling/patterns/.

See the README.md in each directory for more information.

🔬 You can test your commits without appending to a PR by creating a new branch with that extra change and pushing it to your fork. The check-spelling action will run in response to your push -- it doesn't require an open pull request. By using such a branch, you can limit the number of typos your peers see you make. 😉

🗜️ If you see a bunch of garbage

If it relates to a ...

well-formed pattern

See if there's a pattern that would match it.

If not, try writing one and adding it to a patterns/{file}.txt.

Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.

Note that patterns can't match multiline strings.

binary-ish string

Please add a file path to the excludes.txt file instead of just accepting the garbage.

File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.

^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).

@zadjii-msft zadjii-msft added the Needs-Second It's a PR that needs another sign-off label Jan 4, 2022
Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ryan, this is a magnum opus and we're proud to have you contribute it to our humble repo. Thank you.

@DHowett DHowett changed the title 6470 command shell script color tool Add rbeesley's ansi-color.cmd, a CMD-based colortool (& more) Jan 4, 2022
@DHowett DHowett changed the title Add rbeesley's ansi-color.cmd, a CMD-based colortool (& more) Add rbeesley's ansi-color.cmd, a CMD-based color tool (& more) Jan 4, 2022
@DHowett DHowett added the AutoMerge Marked for automatic merge by the bot when requirements are met label Jan 4, 2022
@ghost
Copy link

ghost commented Jan 4, 2022

Hello @DHowett!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit 2420751 into microsoft:main Jan 4, 2022
@ghost
Copy link

ghost commented Feb 3, 2022

🎉Windows Terminal Preview v1.13.10336.0 has been released which incorporates this pull request.:tada:

Handy links:

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-CodeHealth Issues related to code cleanliness, linting, rules, warnings, errors, static analysis, etc. AutoMerge Marked for automatic merge by the bot when requirements are met Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Needs-Second It's a PR that needs another sign-off Product-Meta The product is the management of the products.
Projects
None yet
5 participants